home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************\
- * *
- * menu.c -- menu management functions *
- * *
- \****************************************************************************/
-
- #include "defs.h"
- #include <process.h>
-
- CMD main_menu[] =
- {
- submenu1, "FILE", 2, 76, 1, 3,
- submenu2, "OPTIONS1", 80, 156, 2, 0,
- submenu3, "OPTIONS2", 160, 236, 3, 1,
- submenu4, "OPTIONS3", 240, 316, 0, 2,
- };
-
- CMD menu1[] =
- {
- load_files, "load ", 2, 76, 1, 5,
- null_function, "save", 2, 76, 2, 0,
- null_function, "nothing", 2, 76, 3, 1,
- null_function, "whatever", 2, 76, 4, 2,
- shell, "Shell", 2, 76, 5, 3,
- exit_program, "Exit", 2, 76, 0, 4,
- };
-
- CMD menu2[] =
- {
- null_function, "edit", 80, 156, 1, 2,
- null_function, "load", 80, 156, 2, 0,
- null_function, "save", 80, 156, 0, 1,
- };
-
- CMD menu3[] =
- {
- null_function, "this ",160,236, 1, 3,
- null_function, "that", 160,236, 2, 0,
- null_function, "the other",160,236, 3, 1,
- null_function, "thing", 160,236, 0, 2,
- };
-
- CMD menu4[] =
- {
- null_function, "edit ", 240, 316, 1, 2,
- null_function, "load", 240, 316, 2, 0,
- null_function, "save", 240, 316, 0, 1,
- };
-
- int selection = 0;
- FILE *tstream;
-
- /****************************************************************************\
- * *
- * highlight option -- highlight an option on the main menu *
- * *
- \****************************************************************************/
-
- void highlight_option(int n)
- {
- int y;
-
- y = MENU_TOP + 8;
-
- fg_setcolor(black);
- fg_rect(main_menu[n].x1,main_menu[n].x2,MENU_TOP,MENU_BOTTOM-1);
- fg_setcolor(white);
- center_bstring(main_menu[n].menu_item,main_menu[n].x1,main_menu[n].x2,y);
- }
-
- /****************************************************************************\
- * *
- * horizontal_menu -- main menu containing submenus *
- * *
- \****************************************************************************/
-
- horizontal_menu(CMD cmdtab[],int n,int current)
- {
- register int i, k;
- int c;
- int found, new;
- int ymin, ymax;
- char l;
-
- if (current >= abs(n))
- return(ERR);
-
- ymin = MENU_TOP;
- ymax = ymin + 10;
-
- fg_mousevis(OFF);
-
- /* set up list of options */
-
- if (n < 0)
- {
- for (i = 0; i < abs(n); i++)
- {
- fg_setcolor(white);
- fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
- fg_setcolor(black);
- center_bstring(cmdtab[i].menu_item,cmdtab[i].x1,cmdtab[i].x2,ymax-2);
- }
- fg_save(0,319,MENU_TOP,MENU_BOTTOM);
- }
-
- /* highlight current option */
-
- i = current;
-
- fg_setcolor(black);
- fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
- fg_setcolor(white);
- center_bstring(cmdtab[i].menu_item,cmdtab[i].x1,cmdtab[i].x2,ymax-2);
-
- /* if we're just displaying the menu options, return */
-
- if (n < 0) return(OK);
-
- fg_mousevis(ON);
-
- /* choose an option */
-
- new = current;
- fg_setnum(OFF);
- flushkey();
-
- for(;;)
- {
- /* activate the corresponding vertical menu */
-
- main_option = i;
- c = (*cmdtab[i].menu_func)();
-
- /* cycle through choices */
-
- if (c == LEFT_ARROW || c == BS)
- new = cmdtab[i].prev;
-
- else if (c == RIGHT_ARROW || c == SPACEBAR)
- new = cmdtab[i].next;
-
- else if (c >= 0 && c <= n)
- new = c;
-
- else if (c == ESC)
- {
- exit_program();
- return(i);
- }
-
- else if (isalpha(c))
- {
- c = tolower(c);
- found = FALSE;
- for (k = i+1; k < n; k++)
- {
- l = first_nonblank(cmdtab[k].menu_item);
- if (c == tolower((int)l))
- {
- found = TRUE;
- break;
- }
- }
- if (!found)
- {
- for (k = 0; k <= i; k++)
- {
- l = first_nonblank(cmdtab[k].menu_item);
- if (c == (char)tolower((int)l))
- {
- found = TRUE;
- break;
- }
- }
- }
- if (found)
- new = k;
- else
- {
- main_option = i;
- return(i);
- }
- }
- else
- {
- main_option = i;
- return(i);
- }
-
- if (i != new)
- {
- /* unmark previous option */
-
- fg_mousevis(OFF);
- fg_setcolor(white);
- fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
- fg_setcolor(black);
- center_bstring(cmdtab[i].menu_item,cmdtab[i].x1,cmdtab[i].x2,ymax-2);
-
- /* mark new option */
-
- i = new;
- fg_setcolor(black);
- fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
- fg_setcolor(white);
- center_bstring(cmdtab[i].menu_item,cmdtab[i].x1,cmdtab[i].x2,ymax-2);
- fg_mousevis(ON);
- }
- }
- }
-
- /****************************************************************************\
- * *
- * submenus *
- * *
- \****************************************************************************/
-
- submenu1()
- {
- return(vertical_menu(menu1,0,6));
- }
- submenu2()
- {
- return(vertical_menu(menu2,1,3));
- }
- submenu3()
- {
- return(vertical_menu(menu3,2,4));
- }
- submenu4()
- {
- return(vertical_menu(menu4,3,3));
- }
-
- /****************************************************************************\
- * *
- * vertical_menu -- submenu off main menu *
- * *
- \****************************************************************************/
-
- vertical_menu(CMD cmdtab[],int index,int n)
- {
- register int i, j, k;
- int found, new;
- int height;
- int left, right;
- int string_x;
- int x1, x2, y1, y2;
- int ymin, ymax;
- int count;
- char c, l;
- unsigned char key, aux;
-
- /* height in pixels of an individual menu item */
-
- height = 10;
-
- /* the first menu item determines the x coordinate for the other items */
-
- string_x = get_center(cmdtab[0].menu_item,cmdtab[0].x1,cmdtab[0].x2);
-
- /* define the menu extremes */
-
- x1 = cmdtab[0].x1 - 1;
- x2 = cmdtab[0].x2 + 3;
- y1 = MENU_BOTTOM+1;
- y2 = MENU_BOTTOM + n*height + 1;
-
- /* define the associated horizontal mouse limits */
-
- if (mouse)
- {
- left = mouse_limits[index];
- right = mouse_limits[index+1] - 2;
- }
-
- /* display the vertical menu if necessary */
-
- if (redraw)
- {
- /* do this stuff on the hidden page to make it look faster */
-
- fg_setpage(HIDDEN);
-
- /* draw the menu outline and the shadow around it */
-
- fg_mousevis(OFF);
- fg_setcolor(white);
- fg_box(x1,x2-2,y1,y2-1);
-
- fg_setcolor(dkblue);
- fg_rect(x1+1,x2,y2+1,y2+1);
- fg_rect(x1+2,x2,y2+2,y2+2);
- fg_rect(x2-1,x2,y1,y2+2);
-
- fg_setcolor(black);
- fg_box(x1,x2-2,y1,y2);
-
- /* set up list of options */
-
- ymax = MENU_BOTTOM;
- for (i = 0; i < n; i++)
- {
- ymin = ymax + 1;
- ymax = ymin + height-1;
- fg_setcolor(white);
- fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
- fg_setcolor(black);
- put_bstring(cmdtab[i].menu_item,string_x,ymax-2);
- }
-
- /* highlight first or previously selected option */
-
- i = selection;
- ymin = MENU_BOTTOM + i*height;
- ymax = ymin + height;
- fg_setcolor(black);
- fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
- fg_setcolor(white);
- put_bstring(cmdtab[i].menu_item,string_x,ymax-2);
-
- /* restore the menu to the visual page */
-
- fg_setpage(VISUAL);
- fg_restore(x1,x2,y1,y2+2);
- redraw = FALSE;
- fg_setpage(HIDDEN);
-
- /* clear the hidden page under the menu */
-
- fg_setcolor(blue);
- fg_rect(x1,x2,y1,y2+2);
-
- fg_setpage(VISUAL);
- fg_mousevis(ON);
- }
-
- /* choose an option */
-
- i = selection;
- new = i;
- fg_setnum(OFF);
- flushkey();
-
- for(;;)
- {
- /* read a keystroke */
-
- fg_mousevis(ON);
- fg_waitfor(1);
- fg_intkey(&key,&aux);
-
- /* if using a mouse, check its position */
-
- if (mouse && key+aux == 0)
- {
- fg_mousebut(1,&count,&xmouse,&ymouse);
-
- if (count > 0)
- {
- if (BETWEEN(xmouse,x1,x2) && BETWEEN(ymouse,y1,y2-2))
- {
- new = (ymouse - y1) / height;
-
- /* check if this is the second click of a double click */
-
- if (i == new)
- key = CR;
- }
- else if (!BETWEEN(xmouse,left,right) && BETWEEN(ymouse,MENU_TOP,y1-1))
- {
- fg_mousevis(OFF);
- fg_restore(0,xlimit,MENU_BOTTOM,ylimit);
- redraw = TRUE;
- selection = 0;
- for (j = 0; j <= ITEMS; j++)
- {
- if (BETWEEN(xmouse,mouse_limits[j],mouse_limits[j+1]))
- return(j);
- }
- }
- else
- {
- fg_mousevis(OFF);
- fg_restore(0,xlimit,MENU_BOTTOM,ylimit);
- redraw = TRUE;
- selection = 0;
- return(-1);
- }
- }
- }
-
- /* cycle through choices */
-
- if (aux == UP_ARROW || key == BS)
- new = cmdtab[i].prev;
- else if (aux == DOWN_ARROW || key == SPACEBAR)
- new = cmdtab[i].next;
-
- else if (aux == HOME || aux == PGUP)
- new = 0;
-
- else if (aux == END || aux == PGDN)
- new = n - 1;
-
- else if (aux == LEFT_ARROW || aux == RIGHT_ARROW)
- {
- fg_mousevis(OFF);
- fg_restore(0,xlimit,MENU_BOTTOM,ylimit);
- redraw = TRUE;
- selection = 0;
- return((int)aux);
- }
-
- /* pick one choice */
-
- else if (key == CR)
- {
- (*cmdtab[i].menu_func)();
- wait_for_mouse_buttons();
- selection = i;
- return(index);
- }
-
- else if (key == ESC)
- {
- selection = 0;
- return(ESC);
- }
- else if (isalpha((int)key))
- {
- c = (char)tolower((int)key);
- found = FALSE;
- for (k = i+1; k < n; k++)
- {
- l = first_nonblank(cmdtab[k].menu_item);
- if (c == (char)tolower((int)l))
- {
- found = TRUE;
- break;
- }
- }
- if (!found)
- {
- for (k = 0; k <= i; k++)
- {
- l = first_nonblank(cmdtab[k].menu_item);
- if (c == (char)tolower((int)l))
- {
- found = TRUE;
- break;
- }
- }
- }
- if (found)
- new = k;
- else
- {
- redraw = TRUE;
- return(-1);
- }
- }
- else if (key+aux > 0) /* any other key */
- {
- redraw = TRUE;
- return(-1);
- }
-
- if (i != new)
- {
- /* unmark previous option */
-
- ymin = MENU_BOTTOM + i*height;
- ymax = ymin + height;
- fg_mousevis(OFF);
- fg_setcolor(white);
- fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
- fg_setcolor(black);
- put_bstring(cmdtab[i].menu_item,string_x,ymax-2);
-
- /* mark new option */
-
- i = new;
- ymin = MENU_BOTTOM + i*height;
- ymax = ymin + height;
- fg_setcolor(black);
- fg_rect(cmdtab[i].x1,cmdtab[i].x2,ymin,ymax);
- fg_setcolor(white);
- put_bstring(cmdtab[i].menu_item,string_x,ymax-2);
-
- /* move mouse cursor to the new option */
-
- if (mouse)
- {
- fg_mousepos(&xmouse,&ymouse,&buttons);
- if (BETWEEN(xmouse,x1,x2)) fg_mousemov(xmouse,(ymin+ymax)/2);
- fg_mousevis(ON);
- }
- }
- }
- }
-
- null_function()
- {
- return(OK);
- }
-
- /****************************************************************************\
- * *
- * exit_program -- from menu *
- * *
- \****************************************************************************/
-
- exit_program()
- {
- quit_graphics();
- return(0);
- }
-
- /****************************************************************************\
- * *
- * first_nonblank -- find first character that is not a blank *
- * *
- \****************************************************************************/
-
- char first_nonblank(char *string)
- {
- register int i;
- char c;
-
- i = 0;
- for(;;)
- {
- c = string[i++];
- if (c == 0)
- return(0);
- else if (c > 32)
- return(c);
- }
- }
-
- /****************************************************************************\
- * *
- * shell -- create a DOS command shell *
- * *
- \****************************************************************************/
-
- shell()
- {
- int count;
-
- fg_mousepos(&xmouse,&ymouse,&buttons);
- fg_mousevis(0);
- fg_setmode(3);
- fg_mouseini();
- fg_reset();
-
- /* spawn the DOS command shell */
-
- printf("\nType 'Exit' to return to the menu.\n");
- spawnlp(P_WAIT,"command.com",NULL);
-
- /* upon return from DOS, restore the video context */
-
- fg_setmode(22);
- fg_setpage(0);
- fg_setvpage(0);
- fg_sethpage(1);
- init_mouse();
- fg_mousevis(0);
-
- /* redraw the screen */
-
- draw_screen();
- redraw = TRUE;
-
- fg_mousemov(xmouse,ymouse);
-
- fg_mousebut(1,&count,&xmouse,&ymouse);
- fg_mousebut(2,&count,&xmouse,&ymouse);
-
- return(OK);
- }
-
- /****************************************************************************\
- * *
- * wait_for_mouse_buttons -- wait until no mouse buttons are pressed *
- * *
- \****************************************************************************/
-
- void wait_for_mouse_buttons()
- {
- int buttons;
- int x, y;
-
- if (mouse)
- {
- do
- fg_mousepos(&x,&y,&buttons);
- while (buttons&3);
- }
- }